package com.billionsfinance.hessian.common.zookeeper.client;

import org.apache.commons.lang3.StringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ FileName: ClientSideZkPathChildrenCacheListener.java
 * @ Author: WeiHui-Z
 * @ Date: 2016-11-21  14:52
 * @ Version: v1.0.0
 */
public class ClientSideZkPathChildrenCacheListener implements PathChildrenCacheListener {

	private Logger LOGGER = LoggerFactory.getLogger(ClientSideZkPathChildrenCacheListener.class);

	@Override
	public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
		// 测试发现，至少会受到以下几种（包含但不限于)
		// INITIALIZED
		// CONNECTION_RECONNECTED---意味着不需要自己重连
		// CHILD_REMOVED
		// CHILD_ADDED
		PathChildrenCacheEvent.Type type = event.getType();
		ChildData data = event.getData();
		if (data == null) {
			// 不是我们需要的类型
			LOGGER.debug("event received but no useful, type --- " + type + " data: null");
			return;
		}
		String pathData = new String(data.getData(), "utf-8");  // eg: http://localhost:8080/v4/Hessian/HelloServer,60,60
		// 计算path
		String path = event.getData().getPath();//  eg : /crs/com.billionsfinance.hessian.server.HelloServer/1.0.0/PROVIDER/HelloServer

		LOGGER.info("path --- " + path);
		LOGGER.info("data --- " + pathData);

		path = StringUtils.substringBeforeLast(path, "/");

		// 计算-类型
		ClientSideZkEventType eventType;
		if (PathChildrenCacheEvent.Type.CHILD_ADDED == type) {
			eventType = ClientSideZkEventType.ADD;
		} // 没有更新
		else if (PathChildrenCacheEvent.Type.CHILD_REMOVED == type) {
			eventType = ClientSideZkEventType.REMOVE;
		} else {
			LOGGER.error("unknown message type: " + type);
			return;
		}

		// 构造ZkEvent
		ClientSideZkEvent zkEvent = new ClientSideZkEvent(path, eventType, pathData);
		// 入队
		ClientSideZkEventQueue.put(zkEvent);

		LOGGER.info("zkEvent---" + zkEvent);
	}
}
